package matt.design;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;

public class MapsActivity extends MapActivity {

	private MapController mapController;
	private MapView mapView;
	private LocationManager locationManager;
	private MyLocationOverlay myLocationOverlay;
	private GeoPoint pin, point;
	private Timer longPressTimer;
	private TextView currLocation;
	private Button setLoc;
	private Geocoder geoCoder;
	private Boolean justStarted = false;

	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.main); // bind the layout to the activity
		pin = null;

		currLocation = (TextView) findViewById(R.id.mapLocation);
		setLoc = (Button) findViewById(R.id.mapYes);
		
		setLoc.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				//need to grab the geopoint and the address and store to places in add_task
				Intent intent = new Intent();
				intent.putExtra("Lat", ((Integer)pin.getLatitudeE6()).toString());
				intent.putExtra("Long", ((Integer)pin.getLongitudeE6()).toString());
				intent.putExtra("Address", currLocation.getText().toString());
				setResult(RESULT_OK, intent);
				finish();
			}
		});
		
		// Configure the Map
		mapView = (MapView) findViewById(R.id.map_view);
		mapView.setBuiltInZoomControls(true);
		mapView.setHapticFeedbackEnabled(true);
		mapController = mapView.getController();
		mapController.setZoom(14); // Zoom 1 is world view
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler());

		myLocationOverlay = new MyLocationOverlay(this, mapView);
		MapOverlay mapOverlay = new MapOverlay();
        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.clear();
        listOfOverlays.add(mapOverlay);
        listOfOverlays.add(myLocationOverlay);
        
        mapView.invalidate();

		myLocationOverlay.runOnFirstFix(new Runnable() {
			public void run() {
				mapView.getController().animateTo(myLocationOverlay.getMyLocation());
			}
		});
		
		if(point != null){
	        geoCoder = new Geocoder( getBaseContext(), Locale.getDefault());
	              try {
	                  List<Address> addresses = geoCoder.getFromLocation(point.getLatitudeE6()  / 1E6, point.getLongitudeE6() / 1E6, 1);
	                  currLocation.setText(addresses.get(0).toString());
	              }
	              catch (IOException e) {                
	                  e.printStackTrace();
	              }
		}
		
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	public class GeoUpdateHandler implements LocationListener {

		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			point = new GeoPoint(lat, lng);
			if(justStarted){
				mapController.animateTo(point);
				justStarted = true;
			}

		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}



	@Override
	protected void onResume() {
		myLocationOverlay.enableMyLocation();
		myLocationOverlay.enableCompass();
		super.onResume();
	}

	@Override
	protected void onPause() {
		setResult(RESULT_CANCELED);
		myLocationOverlay.disableMyLocation();
		myLocationOverlay.disableCompass();
		super.onResume();
	}
	
	class MapOverlay extends com.google.android.maps.Overlay
    {		
        @Override
        public boolean draw(Canvas canvas, MapView mapView, 
        boolean shadow, long when) 
        {
            super.draw(canvas, mapView, shadow);                   
            if(pin != null){
	            //---translate the GeoPoint to screen pixels---
	            Point screenPts = new Point();
	            mapView.getProjection().toPixels(pin, screenPts);
	 
	            //---add the marker---
	            Bitmap bmp = BitmapFactory.decodeResource(
	                getResources(), R.drawable.red_pushpin);            
	            canvas.drawBitmap(bmp, screenPts.x, screenPts.y-100, null);  
            }
            return true;
        }
        
        //have to declare outside of method...
        Boolean lPressed = false;
        long delay = 300;
        @Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView) 
        {
        	handleLongpress(event);
        	if(event.getAction() == 1 && lPressed){//user's finger has left the screen and there was a long press
        		pin = mapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY());
        		lPressed = false;
        		
        		geoCoder = new Geocoder( getBaseContext(), Locale.getDefault());
                try {
                    List<Address> addresses = geoCoder.getFromLocation(pin.getLatitudeE6()  / 1E6, pin.getLongitudeE6() / 1E6, 1);
                    String add = "";
                    if (addresses.size() > 0) 
                    {
                        for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++)
                           add += addresses.get(0).getAddressLine(i) + " ";
                    }
                    currLocation.setText(add);
                    
                }
                catch (IOException e) {                
                    e.printStackTrace();
                }  
        	}
			return false;   
        }
    
        private void handleLongpress(final MotionEvent event) {
          	 
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                // Finger has touched screen.
                longPressTimer = new Timer();
                longPressTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                    	lPressed = true;
                    	mapView.performHapticFeedback(1);
                    }
     
                }, delay);
            }
     
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    longPressTimer.cancel();
            }
     
            if (event.getAction() == MotionEvent.ACTION_UP) {
                // User has removed finger from map.
                longPressTimer.cancel();
            }
     
                if (event.getPointerCount() > 1) {
                            // This is a multitouch event, probably zooming.
                    longPressTimer.cancel();
                }
        }
    } 
	
	
	
}